<?php
/**
 * Jabber user data
 */
class Zend_Jabber_User {
    /**
     * jabber user username
     *
     * @var string
     */
    private $username;
    
    /**
     * User jid's domain 
     *
     * @var string
     */
    private $domain;
    
    /**
     * User resource
     *
     * @var stirn
     */
    private $resource = '';
    
    /**
     * User priority
     *
     * @var priority
     */
    private $priority = 0;
    
    /**
     * User alias (String representation of user)
     * 
     * User alias can be specified by distant user himself or changed by connected user
     *
     * @var string
     */
    private $alias;
    
    /**
     * User status string. 
     * 
     * Distant user can provide everything he wans in his status information
     *
     * @var string
     */
    private $status = '';
    
    /**
     * User availability information
     *
     * @var string
     */
    private $show = '';
    
    /**
     * Array of initialized users
     * 
     * @var array
     */
    private static $poll = array();
    
    /**
     * User has gone away
     *
     */
    const SHOW_AWAY = 'away';
    
    /**
     * User is willing to chat
     *
     */
    const SHOW_CHAT = 'chat';
    
    /**
     * Do not desturb this user. 
     * 
     * Messages sent to this user most likely won't be displayed to user, although
     * this depends on implementation of user question
     *
     */
    const SHOW_DND = 'dnd';
    
    /**
     * Extended away. 
     * 
     * Setting such status user says that he is away for a very long period amount of time
     *
     */
    const SHOW_EXTENDED_AWAY = 'xa'; 
    
    /**
     * User is offline
     */
    const SHOW_OFFLINE = 'offline';
    
    /**
     * User is online and ready to response to any message or event
     */
    const SHOW_ONLINE = 'online';
    
    /**
     * Create new user
     *
     * @param string $name User address in "username@domain/resource" format
     * @param string $alias User alias
     */
    private function __construct($jid, $alias = false) {
         $this->alias = $alias ? $alias : $this->username;
         $this->setJid($jid);
    }
    
    /**
     * Get user instance
     *
     * @param string $name User address in "username@domain/resource" format
     * @param string $alias User alias
     * @return Zend_Jabber_User
     */
    public static function getInstance($jid, $alias = false) {
        if(isset(self::$poll[$jid])) {
            return self::$poll[$jid];
        }
        
        return new self($jid, $alias);
    }
    
    /**
     * Set user priority
     *
     * @param integer $priority Priority
     * @throws Zend_Jabber_Exception This exception is thrown when passed priority is out of interval [-127; 128] according to RFC3921 part 2.2.2.3.
     */
    public function setPriority($priority = 0) {
        if(in_array($priority, range(-127, 128))) {
            $this->priority = $priority;
        } else {
            throw new Zend_Jabber_Exception(Zend_Jabber_Exception::CODE_PRIORITY_OUT_OF_RANGE, Zend_Jabber_Exception::MESSAGE_PRIORITY_OUT_OF_RANGE);
        }
    }
    
    /**
     * Get user priority
     *
     * @return integer
     */
    public function getPriority() { 
        return $this->priority;   
    }
    
    /**
     * Set user alias (Diffirently from username alias can change, why alias will be always the same)
     *
     * @param string $alias New user alias
     */
    public function setAlias($alias) {
        $this->alias = $alias;
    }
    
    /**
     * Get user alias
     *
     * @return string
     */
    public function getAlias() {
        return $this->alias;
    }
        
    /**
     * Set user status
     *
     * @param string $status User status
     */
    public function setStatus($status = '') {
        $this->status = $status;
    }
    
    /**
     * Get user status string
     *
     * @return string
     */
    public function getStatus() {
        return $this->status;
    }
    
    /**
     * Set user information by setting his jabber user id
     *
     * @param string $jid Zend_Jabber User Id
     */
    public function setJid($jid) {
        if(!preg_match('/^([^@]+)@([^\/]+)(\/([^\/]+))?$/', $jid, $matches)) {
            throw new Zend_Jabber_Exception('Illegal user name');
        }

        $renamed = false;
        if(isset(self::$poll[$jid])) {
            unset(self::$poll[$jid]);
            $renamed = true;
        }        

        $this->username = $matches[1];
        $this->domain = $matches[2];
        $this->alias = $alias ? $alias : $this->username;
        if(isset($matches[4])) $this->resource = $matches[4];

        if($renamed && isset(self::$poll[$this->getJid()])) {
            throw new Zend_Jabber_Exception('This user is allready exists');
        }
        
        self::$poll[$this->getJid()] = $this;
    }
   
    /**
     * Get full user address in "username@domain/resource" format
     *
     * @return string
     */
    public function getJid($includeResource = true) {
        return $this->getUsername() . "@" . $this->getDomain() .($includeResource ?  ("/"  .  $this->getResource()) : '');
    }
  
    /**
     * Get username
     *
     * @return string
     */
    public function getUsername() {
        return $this->username;
    }

    /**
     * Get server domain to which the user is connected
     *
     * @return string
     */
    public function getDomain() {
        return $this->domain;
    }
    
    /**
     * Get user presence
     *
     * @return string
     */
    public function getResource() {
        return $this->resource;
    }

    /**
     * Set show status (Like online, do not disturb or chat)
     *
     * @param string $value
     */
    public function setShow($value = self::SHOW_ONLINE) {
        if(empty($value)) $value = self::SHOW_ONLINE;
        $this->show = $value;
    }
    
    /**
     * Get user show status
     *
     * @return string
     */
    public function getShow() {
        return $this->show;
    }

    /**
     * Compare two users
     * 
     * @param Zend_Jabber_User $user
     * 
     * @return true
     */
    public function compare(Zend_Jabber_User $user) {
        return $this->getJid(false) == $user->getJid(false);
    }
}
?>